package com.sjc.counter.v1;


import com.google.gson.Gson;
import com.sjc.counter.entity.RequestInfo;
import com.sjc.counter.entity.RequestStat;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Classname ConsoleReporter
 * @Description 以一定频率统计并发送统计数据到命令行
 * ConsoleReporter 类相当于一个上帝类，定时根据给定的时间区间，从数据库中取出数据，借助 Aggregator 类完成统计工作，并将统计结果输出到命令行
 * @Date 2020/5/1 13:47
 * @Created by SangJiacun
 */
public class ConsoleReporter {
    private MetricsStorage metricsStorage;
    private ScheduledExecutorService executor;

    public ConsoleReporter(MetricsStorage metricsStorage) {
        this.metricsStorage = metricsStorage;
        this.executor = Executors.newSingleThreadScheduledExecutor();
    }

    /**
     * 第4个逻辑： 根据给定的时间区间，从数据库中拉去数据
     * @param periodInSeconds  定时控制台打印统计数据的间隔时间
     * @param durationInSeconds 这个时间范围的数据
     */
    public void startRepeatedReport(long periodInSeconds, long durationInSeconds){
        executor.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                // 第1个逻辑：从数据库拉取给定的时间区间的数据
                long durationInMillis = durationInSeconds * 1000;
                long endTimeInMillis = System.currentTimeMillis();
                long startTimeInMillis = endTimeInMillis - durationInMillis;
                Map<String, List<RequestInfo>> requestInfos = metricsStorage.getRequestInfos(startTimeInMillis, endTimeInMillis);

                Map<String, RequestStat> stats = new HashMap<>();
                for (Map.Entry<String, List<RequestInfo>> entry : requestInfos.entrySet()) {
                    String apiName = entry.getKey();
                    List<RequestInfo> requestInfosPerApi = entry.getValue();

                    // 第2个逻辑： 根据原始数据，计算得到统计数据
                    RequestStat requestStat = Aggregator.aggregate(requestInfosPerApi, durationInMillis);
                    stats.put(apiName,requestStat);
                }
                // 第3个逻辑： 将统计数据显示到终端（命名行或邮件）
                System.out.println("Time Span: ["+ startTimeInMillis +", " + endTimeInMillis + "]" );
                Gson gson = new Gson();
                System.out.println(gson.toJson(stats));
            }
        },0,periodInSeconds, TimeUnit.SECONDS);
    }
}
